//
//  LameAudioConvert.m
//  AudioConvertOC
//
//  Created by xyanl on 2025/4/26.
//

#import "LameAudioConvert.h"
#import "lame.h"
#import <AVFoundation/AVFoundation.h>

@implementation LameAudioConvert

/// 音频格式转换 m4a 转成 mp3
/// m4a 8000Hz 单声道
/// - Parameters:
///   - m4aPath: m4a 文件的路径
///   - mp3Path: 转成 mp3 的保存路径
+ (void)convertM4aToMp3:(NSString *)m4aPath mp3Path:(NSString *)mp3Path completion:(void (^)(BOOL success))completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        @try {
            // 输入文件
            NSURL *m4aUrl = [NSURL fileURLWithPath:m4aPath];
            AVURLAsset *asset = [AVURLAsset URLAssetWithURL:m4aUrl options:nil];
            
            // 读取音频数据
            NSError *error = nil;
            AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset error:&error];
            if (error) {
                NSLog(@"Error creating asset reader: %@", error.localizedDescription);
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(NO);
                });
                return;
            }
            
            // 获取音频轨道
            AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];
            if (!track) {
                NSLog(@"No audio track found");
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(NO);
                });
                return;
            }
            
            // 音频输出设置 - 适配8000Hz单声道
            NSDictionary *outputSettings = @{
                AVFormatIDKey: @(kAudioFormatLinearPCM),
                AVLinearPCMBitDepthKey: @16,
                AVLinearPCMIsBigEndianKey: @NO,
                AVLinearPCMIsFloatKey: @NO,
                AVLinearPCMIsNonInterleaved: @NO,
                AVSampleRateKey: @8000.0,
                AVNumberOfChannelsKey: @1
            };
            
            AVAssetReaderTrackOutput *trackOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:outputSettings];
            [reader addOutput:trackOutput];
            [reader startReading];
            
            // 准备输出MP3文件
            FILE *mp3File = fopen([mp3Path UTF8String], "wb");
            if (!mp3File) {
                NSLog(@"Could not create MP3 file");
                dispatch_async(dispatch_get_main_queue(), ^{
                    completion(NO);
                });
                return;
            }
            
            // 初始化LAME - 适配8000Hz单声道
            lame_t lame = lame_init();
            lame_set_in_samplerate(lame, 8000);  // 设置输入采样率
            lame_set_num_channels(lame, 1);      // 单声道
            lame_set_mode(lame, MONO);           // 设置为单声道模式
            lame_set_quality(lame, 5);           // 中等质量
            lame_set_brate(lame, 16);            // 设置比特率为16kbps
            lame_set_VBR(lame, vbr_off);         // 关闭VBR，使用CBR
            
            lame_init_params(lame);
            
            // 缓冲区
            // const int PCM_SIZE = 8192;
            const int MP3_SIZE = 8192;
            // short pcm_buffer[PCM_SIZE];
            unsigned char mp3_buffer[MP3_SIZE];
            
            // 转换过程
            while (reader.status == AVAssetReaderStatusReading) {
                CMSampleBufferRef sampleBuffer = [trackOutput copyNextSampleBuffer];
                if (sampleBuffer) {
                    CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
                    size_t bufferLength = CMBlockBufferGetDataLength(blockBuffer);
                    
                    if (bufferLength > 0) {
                        NSMutableData *data = [NSMutableData dataWithLength:bufferLength];
                        CMBlockBufferCopyDataBytes(blockBuffer, 0, bufferLength, data.mutableBytes);
                        
                        // 转换为PCM数据
                        const short *bytes = (short *)data.bytes;
                        UInt32 numSamples = (UInt32)(bufferLength / sizeof(short));
                        
                        // 写入LAME进行编码（单声道使用lame_encode_buffer）
                        int bytesWritten = lame_encode_buffer(lame, bytes, NULL, numSamples, mp3_buffer, MP3_SIZE);
                        fwrite(mp3_buffer, bytesWritten, 1, mp3File);
                    }
                    
                    CFRelease(sampleBuffer);
                }
            }
            
            // 写入剩余数据
            int bytesWritten = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            if (bytesWritten > 0) {
                fwrite(mp3_buffer, bytesWritten, 1, mp3File);
            }
            
            // 清理资源
            lame_close(lame);
            fclose(mp3File);
            
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(YES);
            });
        } @catch (NSException *exception) {
            NSLog(@"Conversion failed: %@", exception.reason);
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(NO);
            });
        }
    });
}


/// 音频格式转换 caf/pcm 转成 mp3
/// - Parameters:
///   - pcmPath: pcm 文件的路径
///   - mp3Path: 转成 mp3 的保存路径
+ (void)convertPcmToMp3:(NSString *)pcmPath mp3Path:(NSString *)mp3Path completion:(void (^)(BOOL success))completion {
    @try {
        int read, write;
        
        //source 被转换的音频文件位置
        FILE *pcm = fopen([pcmPath cStringUsingEncoding:1], "rb");
        //删除头，否则在前一秒钟会有杂音
        fseek(pcm, 4*1024, SEEK_CUR);
        //output 输出生成的Mp3文件位置
        FILE *mp3 = fopen([mp3Path cStringUsingEncoding:1], "wb");
        
        const int PCM_SIZE = 8192;
        const int MP3_SIZE = 8192;
        short int pcm_buffer[PCM_SIZE*2];
        unsigned char mp3_buffer[MP3_SIZE];
        // 这里要注意，lame的配置要跟AVAudioRecorder的配置一致，否则会造成转换不成功
        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 11025.0);
        lame_set_VBR(lame, vbr_default);
        lame_init_params(lame);
        
        do {
            // 以二进制形式读取文件中的数据
            read = (int)fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
            if (read == 0) {
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            } else {
                write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
            }
            // 二进制形式写数据到文件中
            // mp3_buffer：数据输出到文件的缓冲区首地址
            // write：一个数据块的字节数
            // 1:指定一次输出数据块的个数
            // mp3:文件指针
            fwrite(mp3_buffer, write, 1, mp3);
            
        } while (read != 0);
        
        lame_close(lame);
        fclose(mp3);
        fclose(pcm);
    }
    @catch (NSException *exception) {
        NSLog(@"Conversion failed: %@", exception.reason);
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(NO);
        });
    }
    @finally {
        NSLog(@"MP3生成成功: %@", mp3Path);
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(YES);
        });
    }
}



@end
